package com.sky.skyopsserver.controller;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.sky.skyopsserver.aspect.ApiOperationLog;
import com.sky.skyopsserver.service.HostService;
import com.sky.skyopsserver.utils.PageResponse;
import com.sky.skyopsserver.utils.Response;
import com.sky.skyopsserver.vos.*;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.validation.Valid;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotEmpty;
import jakarta.validation.constraints.NotNull;
import jakarta.validation.constraints.Positive;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import java.util.List;

/**
 * 主机信息控制器
 */
@Slf4j
@RestController
@RequestMapping("/api/host")
@RequiredArgsConstructor
@Validated
@Tag(name = "主机管理", description = "主机信息的增删改查操作")
public class HostController {

    private final HostService hostService;

    /**
     * 添加主机
     */
    @PostMapping("/add")
    @Operation(summary = "添加主机", description = "新增一个主机信息")
    @ApiOperationLog(description = "添加主机")
    public Response<Long> addHost(@Valid @RequestBody HostAddReqVO reqVO) {
        Long hostId = hostService.addHost(reqVO);
        return Response.success(hostId);
    }

    /**
     * 更新主机信息
     */
    @PutMapping("/update")
    @Operation(summary = "更新主机信息", description = "修改主机的基本信息")
    @ApiOperationLog(description = "更新主机信息")
    public Response<Boolean> updateHost(@Valid @RequestBody HostUpdateReqVO reqVO) {
        Boolean result = hostService.updateHost(reqVO);
        return Response.success(result);
    }

    /**
     * 删除主机
     */
    @DeleteMapping("/delete/{id}")
    @Operation(summary = "删除主机", description = "根据ID删除指定主机")
    @ApiOperationLog(description = "删除主机")
    public Response<Boolean> deleteHost(
            @Parameter(description = "主机ID", required = true)
            @PathVariable("id") @NotNull(message = "主机ID不能为空") @Positive(message = "主机ID必须为正数") Long id) {
        Boolean result = hostService.deleteHost(id);
        return Response.success(result);
    }

    /**
     * 批量删除主机
     */
    @DeleteMapping("/batch-delete")
    @Operation(summary = "批量删除主机", description = "根据ID列表批量删除主机")
    @ApiOperationLog(description = "批量删除主机")
    public Response<Boolean> batchDeleteHost(
            @Parameter(description = "主机ID列表", required = true)
            @RequestBody @NotEmpty(message = "主机ID列表不能为空") List<@Positive(message = "主机ID必须为正数") Long> ids) {
        Boolean result = hostService.batchDeleteHost(ids);
        return Response.success(result);
    }

    /**
     * 根据ID查询主机详情
     */
    @GetMapping("/detail/{id}")
    @Operation(summary = "查询主机详情", description = "根据ID获取主机的详细信息")
    @ApiOperationLog(description = "查询主机详情")
    public Response<HostRspVO> getHostById(
            @Parameter(description = "主机ID", required = true)
            @PathVariable("id") @NotNull(message = "主机ID不能为空") @Positive(message = "主机ID必须为正数") Long id) {
        HostRspVO result = hostService.getHostById(id);
        return Response.success(result);
    }

    /**
     * 根据名称查询主机
     */
    @GetMapping("/detail/name/{name}")
    @Operation(summary = "根据名称查询主机", description = "根据主机名称获取主机信息")
    @ApiOperationLog(description = "根据名称查询主机")
    public Response<HostRspVO> getHostByName(
            @Parameter(description = "主机名称", required = true)
            @PathVariable("name") @NotBlank(message = "主机名称不能为空") String name) {
        HostRspVO result = hostService.getHostByName(name);
        return Response.success(result);
    }

    /**
     * 分页查询主机列表
     */
    @PostMapping("/page")
    @Operation(summary = "分页查询主机列表", description = "根据条件分页查询主机信息")
    @ApiOperationLog(description = "分页查询主机列表")
    public PageResponse<HostRspVO> getHostPage(@Valid @RequestBody HostPageReqVO reqVO) {
        IPage<HostRspVO> page = hostService.getHostPage(reqVO);
        return PageResponse.success(page, page.getRecords());
    }

    /**
     * 查询所有主机选项
     */
    @GetMapping("/options")
    @Operation(summary = "查询主机选项", description = "获取所有主机的选项列表，用于下拉选择")
    @ApiOperationLog(description = "查询主机选项")
    public Response<List<HostOptionRspVO>> getAllHostOptions() {
        List<HostOptionRspVO> result = hostService.getAllHostOptions();
        return Response.success(result);
    }

    /**
     * 根据机房ID查询主机选项
     */
    @GetMapping("/options/room/{roomId}")
    @Operation(summary = "按机房查询主机选项", description = "根据机房ID获取主机选项列表")
    @ApiOperationLog(description = "按机房查询主机选项")
    public Response<List<HostOptionRspVO>> getHostOptionsByRoomId(
            @Parameter(description = "机房ID", required = true)
            @PathVariable("roomId") @NotNull(message = "机房ID不能为空") @Positive(message = "机房ID必须为正数") Long roomId) {
        List<HostOptionRspVO> result = hostService.getHostOptionsByRoomId(roomId);
        return Response.success(result);
    }

    /**
     * 根据主机组ID查询主机选项
     */
    @GetMapping("/options/group/{groupId}")
    @Operation(summary = "按主机组查询主机选项", description = "根据主机组ID获取主机选项列表")
    @ApiOperationLog(description = "按主机组查询主机选项")
    public Response<List<HostOptionRspVO>> getHostOptionsByGroupId(
            @Parameter(description = "主机组ID", required = true)
            @PathVariable("groupId") @NotNull(message = "主机组ID不能为空") @Positive(message = "主机组ID必须为正数") Long groupId) {
        List<HostOptionRspVO> result = hostService.getHostOptionsByGroupId(groupId);
        return Response.success(result);
    }

    /**
     * 获取主机统计信息
     */
    @GetMapping("/statistics")
    @Operation(summary = "获取主机统计信息", description = "获取主机的各项统计数据")
    @ApiOperationLog(description = "获取主机统计信息")
    public Response<HostStatisticsRspVO> getHostStatistics() {
        HostStatisticsRspVO result = hostService.getHostStatistics();
        return Response.success(result);
    }

    /**
     * 检查主机名称是否已存在
     */
    @GetMapping("/check-name")
    @Operation(summary = "检查主机名称", description = "检查主机名称是否已存在")
    @ApiOperationLog(description = "检查主机名称")
    public Response<Boolean> checkHostNameExists(
            @Parameter(description = "主机名称", required = true)
            @RequestParam("name") @NotBlank(message = "主机名称不能为空") String name,
            @Parameter(description = "排除的主机ID")
            @RequestParam(value = "excludeId", required = false) Long excludeId) {
        Boolean result = hostService.checkHostNameExists(name, excludeId);
        return Response.success(result);
    }

    /**
     * 检查主机IP是否已存在
     */
    @GetMapping("/check-ip")
    @Operation(summary = "检查主机IP", description = "检查主机IP地址是否已存在")
    @ApiOperationLog(description = "检查主机IP")
    public Response<Boolean> checkHostIpExists(
            @Parameter(description = "IP地址", required = true)
            @RequestParam("ip") @NotBlank(message = "IP地址不能为空") String ip,
            @Parameter(description = "排除的主机ID")
            @RequestParam(value = "excludeId", required = false) Long excludeId) {
        Boolean result = hostService.checkHostIpExists(ip, excludeId);
        return Response.success(result);
    }

    /**
     * 根据名称模糊查询主机
     */
    @GetMapping("/search/name")
    @Operation(summary = "按名称搜索主机", description = "根据主机名称关键字模糊查询主机")
    @ApiOperationLog(description = "按名称搜索主机")
    public Response<List<HostRspVO>> searchHostByName(
            @Parameter(description = "主机名称关键字", required = true)
            @RequestParam("name") @NotBlank(message = "主机名称关键字不能为空") String name) {
        List<HostRspVO> result = hostService.searchHostByName(name);
        return Response.success(result);
    }

    /**
     * 获取机房下的主机列表
     */
    @GetMapping("/list/room/{roomId}")
    @Operation(summary = "获取机房主机列表", description = "获取指定机房下的所有主机")
    @ApiOperationLog(description = "获取机房主机列表")
    public Response<List<HostRspVO>> getHostsByRoomId(
            @Parameter(description = "机房ID", required = true)
            @PathVariable("roomId") @NotNull(message = "机房ID不能为空") @Positive(message = "机房ID必须为正数") Long roomId) {
        List<HostRspVO> result = hostService.getHostsByRoomId(roomId);
        return Response.success(result);
    }

    /**
     * 获取主机组下的主机列表
     */
    @GetMapping("/list/group/{groupId}")
    @Operation(summary = "获取主机组主机列表", description = "获取指定主机组下的所有主机")
    @ApiOperationLog(description = "获取主机组主机列表")
    public Response<List<HostRspVO>> getHostsByGroupId(
            @Parameter(description = "主机组ID", required = true)
            @PathVariable("groupId") @NotNull(message = "主机组ID不能为空") @Positive(message = "主机组ID必须为正数") Long groupId) {
        List<HostRspVO> result = hostService.getHostsByGroupId(groupId);
        return Response.success(result);
    }

    /**
     * 根据主机类型查询主机
     */
    @GetMapping("/list/type/{type}")
    @Operation(summary = "按类型查询主机", description = "根据主机类型查询主机列表")
    @ApiOperationLog(description = "按类型查询主机")
    public Response<List<HostRspVO>> getHostsByType(
            @Parameter(description = "主机类型", required = true)
            @PathVariable("type") @NotBlank(message = "主机类型不能为空") String type) {
        List<HostRspVO> result = hostService.getHostsByType(type);
        return Response.success(result);
    }

    /**
     * 验证主机类型是否有效
     */
    @GetMapping("/validate-type")
    @Operation(summary = "验证主机类型", description = "验证主机类型是否有效")
    @ApiOperationLog(description = "验证主机类型")
    public Response<Boolean> validateHostType(
            @Parameter(description = "主机类型", required = true)
            @RequestParam("type") @NotBlank(message = "主机类型不能为空") String type) {
        Boolean result = hostService.validateHostType(type);
        return Response.success(result);
    }

    /**
     * 验证IP地址格式是否有效
     */
    @GetMapping("/validate-ip")
    @Operation(summary = "验证IP地址", description = "验证IP地址格式是否正确")
    @ApiOperationLog(description = "验证IP地址")
    public Response<Boolean> validateIpAddress(
            @Parameter(description = "IP地址", required = true)
            @RequestParam("ip") @NotBlank(message = "IP地址不能为空") String ip) {
        Boolean result = hostService.validateIpAddress(ip);
        return Response.success(result);
    }

    /**
     * 验证端口是否有效
     */
    @GetMapping("/validate-port")
    @Operation(summary = "验证端口", description = "验证端口号是否有效")
    @ApiOperationLog(description = "验证端口")
    public Response<Boolean> validatePort(
            @Parameter(description = "端口号", required = true)
            @RequestParam("port") @NotNull(message = "端口号不能为空") Integer port) {
        Boolean result = hostService.validatePort(port);
        return Response.success(result);
    }

    /**
     * 测试主机连接
     */
    @PostMapping("/test-connection/{id}")
    @Operation(summary = "测试主机连接", description = "测试指定主机的连接状态")
    @ApiOperationLog(description = "测试主机连接")
    public Response<Boolean> testHostConnection(
            @Parameter(description = "主机ID", required = true)
            @PathVariable("id") @NotNull(message = "主机ID不能为空") @Positive(message = "主机ID必须为正数") Long id) {
        Boolean result = hostService.testHostConnection(id);
        return Response.success(result);
    }

    /**
     * 移动主机到主机组
     */
    @PostMapping("/move-to-group")
    @Operation(summary = "移动主机到主机组", description = "将指定主机移动到目标主机组")
    @ApiOperationLog(description = "移动主机到主机组")
    public Response<Boolean> moveHostsToGroup(
            @Parameter(description = "主机ID列表", required = true)
            @RequestParam("hostIds") @NotEmpty(message = "主机ID列表不能为空") List<@Positive(message = "主机ID必须为正数") Long> hostIds,
            @Parameter(description = "目标主机组ID", required = true)
            @RequestParam("targetGroupId") @NotNull(message = "目标主机组ID不能为空") @Positive(message = "目标主机组ID必须为正数") Long targetGroupId) {
        Boolean result = hostService.moveHostsToGroup(hostIds, targetGroupId);
        return Response.success(result);
    }

    /**
     * 移动主机到机房
     */
    @PostMapping("/move-to-room")
    @Operation(summary = "移动主机到机房", description = "将指定主机移动到目标机房")
    @ApiOperationLog(description = "移动主机到机房")
    public Response<Boolean> moveHostsToRoom(
            @Parameter(description = "主机ID列表", required = true)
            @RequestParam("hostIds") @NotEmpty(message = "主机ID列表不能为空") List<@Positive(message = "主机ID必须为正数") Long> hostIds,
            @Parameter(description = "目标机房ID", required = true)
            @RequestParam("targetRoomId") @NotNull(message = "目标机房ID不能为空") @Positive(message = "目标机房ID必须为正数") Long targetRoomId) {
        Boolean result = hostService.moveHostsToRoom(hostIds, targetRoomId);
        return Response.success(result);
    }

    /**
     * 获取所有主机名称列表
     */
    @GetMapping("/names")
    @Operation(summary = "获取主机名称列表", description = "获取所有主机的名称列表")
    @ApiOperationLog(description = "获取主机名称列表")
    public Response<List<String>> getAllHostNames() {
        List<String> result = hostService.getAllHostNames();
        return Response.success(result);
    }

    /**
     * 获取所有主机IP列表
     */
    @GetMapping("/ips")
    @Operation(summary = "获取主机IP列表", description = "获取所有主机的IP地址列表")
    @ApiOperationLog(description = "获取主机IP列表")
    public Response<List<String>> getAllHostIps() {
        List<String> result = hostService.getAllHostIps();
        return Response.success(result);
    }

    /**
     * 根据机房ID获取主机数量
     */
    @GetMapping("/count/room/{roomId}")
    @Operation(summary = "获取机房主机数量", description = "获取指定机房下的主机数量")
    @ApiOperationLog(description = "获取机房主机数量")
    public Response<Long> getHostCountByRoomId(
            @Parameter(description = "机房ID", required = true)
            @PathVariable("roomId") @NotNull(message = "机房ID不能为空") @Positive(message = "机房ID必须为正数") Long roomId) {
        Long result = hostService.getHostCountByRoomId(roomId);
        return Response.success(result);
    }

    /**
     * 根据主机组ID获取主机数量
     */
    @GetMapping("/count/group/{groupId}")
    @Operation(summary = "获取主机组主机数量", description = "获取指定主机组下的主机数量")
    @ApiOperationLog(description = "获取主机组主机数量")
    public Response<Long> getHostCountByGroupId(
            @Parameter(description = "主机组ID", required = true)
            @PathVariable("groupId") @NotNull(message = "主机组ID不能为空") @Positive(message = "主机组ID必须为正数") Long groupId) {
        Long result = hostService.getHostCountByGroupId(groupId);
        return Response.success(result);
    }

    /**
     * 获取过期主机列表
     */
    @GetMapping("/expired")
    @Operation(summary = "获取过期主机", description = "获取已过期的主机列表")
    @ApiOperationLog(description = "获取过期主机")
    public Response<List<HostRspVO>> getExpiredHosts() {
        List<HostRspVO> result = hostService.getExpiredHosts();
        return Response.success(result);
    }

    /**
     * 获取即将过期主机列表
     */
    @GetMapping("/expiring-soon")
    @Operation(summary = "获取即将过期主机", description = "获取指定天数内即将过期的主机列表")
    @ApiOperationLog(description = "获取即将过期主机")
    public Response<List<HostRspVO>> getHostsExpiringSoon(
            @Parameter(description = "天数", required = true)
            @RequestParam("days") @NotNull(message = "天数不能为空") @Positive(message = "天数必须为正数") Integer days) {
        List<HostRspVO> result = hostService.getHostsExpiringSoon(days);
        return Response.success(result);
    }
}